package dbPicasso::PluginRegistry;

use FindBin;
use File::Basename;
use Data::Dumper;

use UNIVERSAL qw(isa can);


use vars qw( %PLUGINS %REGISTRY);


&init_plugins;


sub init_plugins
{
	while (<$FindBin::Bin/lib/dbPicasso/Plugin/*.pm>)
	{
		my $pluginname = basename($_);

		$pluginname =~ s/.pm$//;
		
		my $pluginmod = "dbPicasso::Plugin::$pluginname";
		print "*** Attempting to init plugin '$pluginname'...\n";

		eval "require $pluginmod";

		if ($@)
		{
			print "WARNING: Unable to load plugin $pluginname ($pluginmod)\n";
			print "Error was: $@\n";
		}

		$PLUGINS{$pluginname} = $pluginmod->init;
	}

	print "After init_plugins, PLUGINS contains: " . Dumper(\%PLUGINS);

	return 1;

}


sub register
{
	my $self = shift;
	my $event = shift;
	my $callback = shift;
	my $widgets = shift; 

	# Use the plugin package name as the identifier.

	my ($name) = ref($self) =~ /::([a-z_]+)$/i;

	my %events = (
			'on_app_start' => 1,
			'before_query' => 1,
			'after_query' => 1,
			'on_app_shutdown' => 1,
			'before_connect' => 1,
			'after_connect' => 1,
			'before_disconnect' => 1,
			'after_disconnect' => 1,
			'on_connect_failed' => 1,
		     );

	return undef unless ($events{$event} and ref($callback) eq 'CODE');

	$REGISTRY{$event} = [] unless $REGISTRY{$event};

	push @{ $REGISTRY{$event} }, {
					callback => $callback,
					widgets => $widgets,
					plugin => $self,
				};

	return 1;
}

sub fire_event
{
	my $class = shift;
	my $event = shift;
	my $glade = shift;

	my %widgets;

	return 1 unless ($REGISTRY{$event}); # just report success if nothing is registered.

	foreach $plugindef(@{$REGISTRY{$event}})
	{
		my %pluginwidgets = ();
		map {
			$pluginwidgets{$_} = $widgets{$_} ? $widgets{$_}
							  : $widgets{$_} = $glade->get_widget($_); # assign for next time
		} @{ $$plugindef{widgets} };	

		my $plugin = $$plugindef{plugin};
		my $callback = $$plugindef{callback};

		$plugin->$callback(\%pluginwidgets, @_);
	}

}

1;
